#include "kernel.h"

void ipi_handler(struct trapframe_t tf)
{
	 int result = 0;
	 int cpu = cur_cpu();
	 if (cpus[cpu].ipi_recv_lock == 0) return;
	 if (cpus[cpu].ipi_func == IPI_IDLE) goto ipi_finish;

	 switch (cpus[cpu].ipi_func)
	 {
	 case IPI_WAIT:
	 {
		  result = sch_wait(cpus[cpu].ipi_arg0,
							cpus[cpu].ipi_arg1,
							(spin_lock_t *)cpus[cpu].ipi_arg2);
		  break;
	 }
	 case IPI_NOTIFY:
	 {
		  result = sch_notify(cpus[cpu].ipi_arg0,
							  cpus[cpu].ipi_arg1);
		  break;
	 }
	 }

ipi_finish:
	 cpus[cpu].ipi_func = IPI_IDLE;
	 
	 spl_release(&cpus[cpu].ipi_recv_lock);
	 spl_release(&cpus[cpus[cpu].ipi_source].ipi_send_lock);

	 if (result == -E_YIELD)
	 {
		  call_yield();
	 }
}
